{
    title:  'ESP Controllers',
    crumbs: [
        { "User's Guide": 'index.html' },
    ],
}
        <h1>Controllers and Actions</h1>
        <p>ESP <em>controllers</em> are the conductors of the application and they orchestrate the application's 
        logic and responses to client requests. Via <em>action</em> functions, they receive client requests and 
        generate appropriate responses, mutating the applications data model as required.</p>
        <p>An ESP controller is a "C" source file that contains action functions to receive to incoming client 
        requests and manage the applications response. The controller may be part of an ESP MVC application or it
        may be a stand-alone controller.</p>

        <a id="example"></a>
        <h2>Example of a Controller</h2>
        <p>So what does a controller look like? Here is a partial example called <em>controllers/greeting.c</em>
        that has one action to say "Hello World".</p>
        <pre class="code">
#include "esp.h"

static void hello() { 
    render("Hello World\n");
}

ESP_EXPORT int esp_controller_test_greeting(HttpRoute *route) 
{
    espDefineAction(route, "greeting-hello", hello);
    return 0;
}
</pre>
        <p>If the client browser issues a request for:</p>
        <pre class="code">http://localhost/greeting/hello</pre>
        <p>ESP will compile the greeting.c controller and then load the controller and
        run the <em>hello</em> function which will respond to the client with "Hello World\n".</p>
 
        <a id="flow"></a>
        <h2>Controller Processing</h2>
        <p>ESP process requests in stages:</p>
        <ol>
            <li>Decode the URI and web request</li>
            <li>Route an incoming request to the ESP request handler</li>
            <li>If the request is for a controller, load the controller and run the requested action</li>
            <li>Run the specified controller action determined by the request route pattern</li>
            <li>If the request is for a web page or if the controller did not render a response 
                look for a matching web page and run that to render a response</li>
        </ol>
  
        <a id="routing"></a>
        <h2>Routing Requests</h2>
        <p>At the heart of understanding how controllers are loaded and actions are run, is understanding request
        routing. When the HTTP server inside <em>esp</em>receives a client request, it examines each of the 
        configured request routes. These may are configured via the <em>esp.json</em> file. 
        Esp then searches the route table, until it finds a matching route for the request URI. The 
        selected route will then break the URI into tokens and save the token values as request parameters.</p>
        <p>For example: consider the URI format:</p>
        <pre class="code">
http://example.com/APP/CONTROLLER/ACTION/ID
</pre>
        <p>In this example, <em>APP</em> is the (optional) name of the application, <em>CONTROLLER</em> is the controller
        name, <em>ACTION</em> is the name of the action method to run and <em>ID</em> is a selector for an element
        in the Model. When the request URI is tokenized, the ESP HTTP router will extract the controller name and then
        use this name to load the appropriate controller to service the request.</p>

        <h3>Restful Routes</h3>
        <p>ESP applications will typically use a collection of Restful routes.
        Restful routes are a simple, readable, and familiar pattern for many developers and users. 
        They map common <a href="http://en.wikipedia.org/wiki/Create,_read,_update_and_delete">CRUD</a> 
        operations to specific URIs and controller actions.</p>
        <p>ESP will create a initial set of Restful routes depending on the <em>esp.server.routes</em> configuration.</p>
<table class="ui table" title="routes">
    <thead>
<tr><th>Description</th><th>Method</th><th>Pattern</th><th>Action</th></tr>
    </thead>
    <tbody>
<tr><td>controller</td><td>GET</td><td>/controller$</td><td>${controller}</td></tr>
<tr><td>delete</td><td>POST</td><td>/controller/{id=[0-9]+}/delete$</td><td>delete</td></tr>
<tr><td>create</td><td>POST</td><td>/controller(/)*$</td><td>create</td></tr>
<tr><td>edit</td><td>GET</td><td>/controller/{id=[0-9]+}/edit$</td><td>edit</td></tr>
<tr><td>get</td><td>GET</td><td>/controller/{id=[0-9]+}$</td><td>get</td></tr>
<tr><td>init</td><td>GET</td><td>/controller/init$</td><td>init</td></tr>
<tr><td>list</td><td>GET</td><td>/controller/list$</td><td>list</td></tr>
<tr><td>stream</td><td>GET</td><td>/controller/stream$</td><td>stream</td></tr>
<tr><td>remove</td><td>DELETE</td><td>/controller/{id=[0-9]+}$</td><td>remove</td></tr>
<tr><td>update</td><td>PUT</td><td>/controller/{id=[0-9]+}/{action}(/)*$</td><td>update</td></tr>
<tr><td>action</td><td>GET,POST</td><td>/controller//{id=[0-9]+}{action}$</td><td>${controller}/${action}</td></tr>
    </tbody>
</table>
    <p>The delete route is a POST method variant of remove. The stream route is for WebSockets streaming of
    updates. </p>

            <a id="actions"></a>
            <h2>Actions</h2>
            <p>Actions are where the controller does its work. In ESP, actions are simple "C" functions and thus
            they need to be registered with ESP before use. This is done in the controller module initialization function. 
            The initialization function is named: <em>esp_controller_NAME</em>, where NAME is the unique 
            name of the controller. The first time the controller is invoked, the controller
            module will be loaded and the initialization function will be run. Typically, the initialization function 
            will then call
            <a href="../ref/api/esp.html#group___esp_route_1ga321abe89cc91246b2a44f40493988670">espDefineAction</a> 
            to bind action functions to route actions.</p>
<pre class="code">
#include "esp.h"
/* Actions */
static FUNCTION() {
    ...
}
/*
    Controller module initialization routine
 */
ESP_EXPORT int esp_controller_APP_NAME(HttpRoute *route) 
{
    espDefineAction(route, "NAME-ACTION", FUNCTION);
    return 0;
}
</pre>
            <p>If you want to programmatically bind a C function to a URI without creating a loadable module and without
            defining explicitly creating a route
            you can call the <a href="../ref/api/esp.html#group___esp_route_1ga0d812aed0ff96f0ffa281860270e8910">espBindProc</a>
            API. This will create a new route by inheriting settings from an existing route and then define an action
            based on the supplied URI pattern. Because this creates a new route for each callback, it is best not to use
            if you have many callbacks.</p>
            <pre class="code">espBindProc(route, "/do/something", callback);</pre>
            <h3>Missing Actions</h3>
            <p>When responding to a request, if the required controller and action is not found, ESP will look for a
            corresponding ESP page of the same name. If that is not defined, ESP will respond with an HTTP 404 
            error indicating that the required action and page could not be found.</p>
            
            <a id="processing"></a>
            <h3>Processing the Request</h3>
            <p>The controller action can perform any processing it desires. There are no real restrictions except you don't
            want to block for too long without giving the client some feedback. Because ESP is multithreaded, you can
            block. In that case, the server will continue to run and serve other requests. However, note that threads
            are a limited resource. It may be better to use non-blocking techniques such as async processing.</p>
            <h3>Async Processing</h3>
            <p>An action may service a long-running request without blocking, by responding in pieces. 
            An action function may return without completing the request. Normally, ESP will automatically finalize
            the request when the action returns. To prevent this, call 
            <a href="../ref/api/esp.html#group___esp_abbrev_1ga9db9b8b7e2c750f6f942da0478866de2">
            dontAutoFinalize</a> to tell ESP not to finalize the request and to keep the connection and
                response open. At anytime and from any other code, you may then call 
                <a href="../ref/api/esp.html#group___esp_abbrev_1ga32d626626eee0bc4ade146973f6abb1c">finalize</a>
                to complete the request. To force output to the client, without finalizing, use 
                <a href="../ref/api/esp.html#group___esp_abbrev_1ga32d626626eee0bc4ade146973f6abb1c">flush</a>.</p>
            <p>For example:</p>
<pre class="code">
static void second(HttpConn *conn) {
    setConn(conn);
    render("World\n");
    finalize();
}
static void first() {
    dontAutoFinalize();
    render("Hello ");
    flush();
    <b>setTimeout(second, 5000, getConn());</b>
}
</pre>
            <p>This example will print "Hello ", then wait five seconds and then print "World". Note that the request
            is held open, but ESP is not blocked in any thread. The call to <em>setTimeout</em> will arrange to have
            the ESP event loop invoke <em>second</em> after five seconds have elapsed. This pattern is a 
            highly efficient in its use of system resources and scales very well.</p>

            <h3>Request Timeout Limits</h3>
            <p>ESP has a request timeout and a request inactivity timeout. If a request duration exceeds the limit
            defined via the <em>timeouts.request</em> directive in <em>esp.json</em>, the request will be aborted. 
            If the request does no I/O for more than the limit specified by the <em>timeouts.inactivity</em>
            it will be similarly aborted. These limits can be set per route in <em>esp.json</em>.</p>

            <h2>Loading and Caching Controllers</h2>
            <p>Before a controller can run, it must first be compiled and linked into a loadable library.
            On Windows, this will be a DLL, on Unix, it will be a shared library with a ".so" extension. On VxWorks it
            will be a loadable task module.</p>
            <p>The compilation of controllers into libraries happens automatically if a compiler is installed on the
            system and if the <em>EspUpdate</em> directive is enabled. If so, when a request is received, ESP will
            compile and link the controller as a library and save the result into the ESP <em>cache</em> directory
            for future use. After servicing the first request for the controller, the controller code is retained in
            memory and the controller will not be reloaded unless the source code is modified. If ESP is rebooted,
            the cached library will be reloaded without recompiling. This provides two levels of caching: in-memory and
            on-disk as a shared library.</p>
            <h3>Development and Production Modes</h3>
            <p>When a request for a controller is received, ESP will test if the source code has been updated to
            determine if the controller must be recompiled. If the source has been changed, ESP will wait for all
            requests that are using the already loaded controller, to gracefully complete. When no requests are using
            the old controller version, ESP will unload the controller, and ESP will recompile the updated controller
            source and create a new shared library that will then be loaded and the request servicing resumed.</p>
            <p>If ESP was configured and built in debug mode, the default value for <em>EspUpdate</em> will be
            <em>on</em>. If ESP was built in release mode, the default value is <em>off</em>. In release mode is it
            common practice to lock down the compiled controllers and not auto-recompile once deployed.</p>

            <a id="context"></a>
            <h2>Controller Context</h2>
            <p>ESP establishes a request context for the controller before invoking the controller action. The top level 
            of the context is represented by the <a href="../ref/api/http.html#group___http_conn">HttpConn</a> 
            connection object. From this, all other request information can be reached, including the:</p>
            <ul>
                <li>HttpRx object &mdash; describes the client HTTP request.</li>
                <li>HttpTx object &mdash; describes the client HTTP response.</li>
                <li>HttpHost object &mdash; describes the web server hosting the application.</li>
                <li>params &mdash; request query, form, and routing parameters.</li>
                <li>session state object &mdash; session state information.</li>
            </ul>
            <h3>ESP Short-Form API</h3>
            <p>ESP defines a terse, short-form, 
            <a href="../ref/api/esp.html#group___esp_abbrev">API</a> that uses the current connection object to
            provide context for the API. When using this API, explicit access to the connection object should not 
            typically be required. The ESP short-form API should cover 95% of requirements for action processing.</p>
            
            <h3>Explicit Connection Access</h3>
            <p>If explicit access to the connection object is required, action functions may
            define a connection argument as 
            which is passed into all actions.</p>
<pre class="code">static void ACTION(HttpConn *conn) {
    /* Use the conn reference here */
}</pre> 
            <p>Alternatively, the connection object can can be retrieved using the <a
                href="../ref/api/esp.html#group___esp_abbrev_1gabe448b3542b4d1391e80e74192a09cb3">
                getConn</a> API.</p>
            <h3>Navigating the Connection Object</h3>
            <p>The <a href="../ref/api/http.html#group___http_conn">HttpConn</a> object represents the current
            TCP/IP connection. By using HTTP KeepAlive, the connection may be utilized for multiple requests. The fields
            of the HttpConn object are public and can be accessed and
            navigated.</p> 
            <table class="table ui" title="properties">
                <thead>
                    <tr><th>HttpConn Property</th><th>Purpose</th></tr>
                </thead>
                <tbody>
                    <tr><td>rx</td><td>Reference to the HttpRx receive object</td></tr>
                    <tr><td>tx</td><td>Reference to the HttpTx transmit object</td></tr>
                    <tr><td>host</td><td>Reference to the HttpHost object</td></tr>
                    <tr><td>http</td><td>Reference to the Http object</td></tr>
                    <tr><td>endpoint</td><td>Reference to the HttpEndpoint transmit object</td></tr>
                    <tr><td>limits</td><td>Reference to the HttpLimits object</td></tr>
                    <tr><td>ip</td><td>Remote client IP address</td></tr>
                    <tr><td>port</td><td>Remote client port</td></tr>
                </tbody>
            </table>
            <h3>Navigating the Receive Object</h3>
            <p>The <a href="../ref/api/http.html#group___http_rx">HttpRx</a> object represents the receive side of the
            HTTP protocol. On the server, it holds state regarding the client HTTP request. The fields of the HttpRx
            object are public and can be accessed and navigated.</p> 
            <table class="table ui" title="fields">
                <thead>
                    <tr><th>HttpRx Property</th><th>Purpose</th></tr>
                </thead>
                <tbody>
                    <tr><td>method</td><td>HTTP request method</td></tr>
                    <tr><td>uri</td><td>Current URI (may be rewritten)</td></tr>
                    <tr><td>pathInfo</td><td>Path portion of the URI after the scriptName</td></tr>
                    <tr><td>scriptName</td><td>ScriptName portion of the URI</td></tr>
                    <tr><td>length</td><td>Content length</td></tr>
                    <tr><td>route</td><td>Reference to current HttpRoute object</td></tr>
                    <tr><td>params</td><td>Request params (query, form and route parameters)</td></tr>
                    <tr><td>files</td><td>Uploaded files</td></tr>
                </tbody>
            </table>
            <h3>Navigating the Tx Object</h3>
            <p>The <a href="../ref/api/http.html#group___http_tx">HttpTx</a> object represents the transmit side of the
            HTTP protocol. On the server, it holds state regarding the response to the client. The fields of the HttpTx
            object are public and can be accessed and navigated.</p> 
            <table class="table ui" title="state">
                <thead>
                    <tr><th>HttpTx Property</th><th>Purpose</th></tr>
                </thead>
                <tbody>
                    <tr><td>filename</td><td>Name of the real file being served</td></tr>
                    <tr><td>ext</td><td>Filename extension</td></tr>
                    <tr><td>handler</td><td>Request handler object</td></tr>
                    <tr><td>length</td><td>Response content length</td></tr>
                    <tr><td>status</td><td>Response HTTP status</td></tr>
                    <tr><td>headers</td><td>Response HTTP headers</td></tr>
                </tbody>
            </table>
            
            <a id="models"></a>
            <h3>Sample of ESP API</h3>
            <p>Here are a few of the ESP APIs that may be used inside controller actions:</p>
            <table class="table ui" title="viewClass">
                <thead>
                    <tr>
                        <th class="nowrap">Method / Property</th>
                        <th>Description</th>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                        <td><a href="../ref/api/esp.html#group___esp_abbrev_1gadba1deb080e78b4517119a0294489b44">
                                addHeader</a></td> <td>Add a response HTTP header.</td>
                    </tr>
                    <tr>
                        <td><a href="../ref/api/esp.html#group___esp_abbrev_1gab7b4049b554576b57f8cc49efc9e3a95">
                                createSession</a>
                        </td>
                        <td>Enable session control.</td>
                    </tr>
                    <tr>
                        <td><a href="../ref/api/esp.html#group___esp_abbrev_1ga35677b9aa8d61543db5ea80377e823a6">
                            destroySession</a>
                        </td>
                        <td>Destroy a session.</td>
                    </tr>
                    <tr>
                        <td><a href="../ref/api/esp.html#group___esp_abbrev_1ga9db9b8b7e2c750f6f942da0478866de2">
                                dontAutoFinalize</a>
                        </td>
                        <td>Don't automatically finalize output when the action returns. Useful for async actions.</td>
                    </tr>
                    <tr>
                        <td><a href="../ref/api/esp.html#group___esp_abbrev_1ga03544bf56dde3a257391d07e1d6f6a3a">
                                error</a>
                        </td>
                        <td>Send an error flash message to the next web page.</td>
                    </tr>
                    <tr>
                        <td><a href="../ref/api/esp.html#group___esp_abbrev_1ga8e8c0dccb4ded8a2fecec11d389cf8c8">
                                inform</a>
                        </td>
                        <td>Send an informational flash message to the next web page.</td>
                    </tr>
                    <tr>
                        <td><a href="../ref/api/esp.html#group___esp_abbrev_1gad638c34898123293ebc120c1f9396a9c">
                            param</a>
                        </td>
                        <td>Get a request parameter value.</td>
                    </tr>
                    <tr>
                        <td><a href="../ref/api/esp.html#group___esp_abbrev_1ga79cf206805a9595395af14e7c35f289d">
                                redirect</a></td>
                        <td>Redirect the client to a new URI.</td>
                    </tr>
                    <tr>
                        <td><a href="../ref/api/esp.html#group___esp_abbrev_1gaf89154adc3cbf6d6a6a32c6b4457c593">
                                render</a></td>
                        <td>Render the text data back to the client.</td>
                    </tr>
                    <tr>
                        <td><a href="../ref/api/esp.html#group___esp_abbrev_1gaa1e37f244a0e0796df494dfb756472a8">
                                renderFile</a></td>
                        <td>Render a file's contents back to the client.</td>
                    </tr>
                    <tr>
                        <td><a href="../ref/api/esp.html#group___esp_abbrev_1gafe8d897ff436eabc6fc275f76222a5c3">
                                setContentType</a></td>
                        <td>Set the response content type.</td>
                    </tr>
                    <tr>
                        <td><a href="../ref/api/esp.html#esp_8h_1a85b884db9ea1993efaa01dbe686f601c">
                                setCookie</a></td>
                        <td>Define a cookie to include in the response.</td>
                    </tr>
                    <tr>
                        <td><a href="../ref/api/esp.html#group___esp_abbrev_1gadb4f7bc3020ab9c481f1ebcaf1ed3f2a">
                                setSessionVar</a></td>
                        <td>Set a variable in session state storage.</td>
                    </tr>
                    <tr>
                        <td><a href="../ref/api/esp.html#group___esp_abbrev_1ga56d17d8860dc351f63feaa55891cdf21">
                                uri</a></td>
                        <td>Make a URI from parameters.</td>
                    </tr>
                </tbody>
            </table>
            
            <a id="parameters"></a>
            <h2>Request Parameters</h2>
            <p>ESP will collect request query, form data and route parameters into one
            <em>params</em> object which is accessible to actions via the 
            <a href="../ref/api/esp.html#group___esp_abbrev_1gad638c34898123293ebc120c1f9396a9c">param</a> API. Each query key/value pair and all
            request form elements posted by the client will become a properties of the <em>params</em> object.
            When routing the request, ESP will tokenize the URI and create parameters for each positional token in
            the URI. The Controller name and Action are defined as the parameters: <em>controller</em> and 
            <em>token</em>.</p>
            <a id="views"></a>
            <h3>Rendering Views</h3>
            <p>After processing the request, the controller is responsible for rendering a response back to the client. 
            The controller can choose how to respond. It may explicitly create the response body by calling
            <a href="../ref/api/esp.html#group___esp_abbrev_1gaf89154adc3cbf6d6a6a32c6b4457c593">render</a> to generate HTML.
            Alternatively, the action may call 
            <a href="../ref/api/esp.html#group___esp_abbrev_1gaf0db430f850378bd83c514a0dda77fb9">renderView</a> to 
            response with a view web page.
            
            If the action method does not explicitly generate any response, ESP will invoke a view with the same name as
            the action method.</p>

            <a id="generating"></a>
            <h2>Generating Controllers and Actions</h2>
            <p>If you are creating an MVC application, you may use the ESP application generator, called <em>esp</em> to
            generate controllers, actions and controller scaffolds. To generate a new controller, run:</p>
            <pre class="code">
esp generate controller name [actions...]
</pre>
            <p><em>name</em> is the controller name. <em>actions...</em> are the names of the action functions you 
            want to generate. This command will create the controller source file under the <em>controllers</em> directory. 
            <p>If no actions are requested when generating, <em>esp</em> will create a controller with 
            an initialization function but without any actions. If actions are specified, <em>esp</em> 
            will create an empty action method for each specified action. You can safely edit the
            controller source to meet your needs.</p>

            <p>For example, if you use the command:</p>

            <pre class="code">$ <b>esp generate controller admin edit login logout command</b></pre>

            <p>The following controller code will be generated. There is one function generated for each action 
            and a call to <em>espDefineAction</em> is added to register the controller. The <em>esp_controller_admin</em>
            initialization function is invoked once when the controller is first loaded.</p>

            <pre class="code">#include "esp.h"

static void edit() {}
static void login() {}
static void logout() {}
static void command() {}

ESP_EXPORT int esp_controller_demo_admin(HttpRoute *route) 
{
    espDefineAction(route, "admin/edit", edit);
    espDefineAction(route, "admin/login", login);
    espDefineAction(route, "admin/logout", logout);
    espDefineAction(route, "admin/command", command);
    return 0;
}
</pre>
